﻿using System;

namespace GeoFits
{
    /// <summary>
    /// 几何图形类：圆
    /// </summary>
    public class Circle : Geometry
    {
        #region 变量和属性
        private Point _center;
        private Vector _normal;
        /// <summary>
        /// 圆心
        /// </summary>
        /// <value>圆心位置</value>
        public Point Center
        {
            get
            {
                return _center;
            }
            set
            {
                _center = value;
            }
        }
        /// <summary>
        /// 半径
        /// </summary>
        /// <value>半径长度</value>
        public double Radius { get; set; }

        /// <summary>
        /// <para>是否为平面圆</para>
        /// </summary>
        /// <remarks>注意:当为平面圆时Normal和圆心的Z坐标将不再起作用。</remarks>
        public bool IsPlaneCircle { get; set; }
        /// <summary>
        /// <para>圆所在平面的法向量</para>
        /// </summary>
        /// <remarks>注意:只有当IsPlaneCircle为False时这个属性才有作用。</remarks>
        public Vector Normal
        {
            get
            {
                return _normal;
            }
            set
            {
                if (value.Length == 0.0)
                {
                    throw new Exception("法向量不能为0向量！");
                }
                _normal = value.Normalize();
            }
        }

        #endregion
        /// <summary>
        /// <para>构造平面圆参数</para>
        /// </summary>
        /// <remarks>此时圆心为(0, 0, 0)，法向量为(0, 0, 1)的平面圆。</remarks>
        public Circle()
        {
            Normal = new Vector(0, 0, 1);
            Center = new Point(0, 0, 0);
            IsPlaneCircle = true;
        }
        /// <summary>
        /// 构造圆参数
        /// </summary>
        /// <param name="pt">圆心</param>
        /// <param name="radius">半径</param> 
        /// <param name="normal">法向量</param>
        /// <exception cref="System.Exception">法向量为(0, 0, 0)时抛出异常</exception>
        /// <remarks>不指定或为null时为平面圆。</remarks>
        public Circle(Point pt, double radius, Vector normal = null)
        {
            Center = pt;
            Radius = radius;
            if (normal == null)
            {
                IsPlaneCircle = true;
                Normal = new Vector(0, 0, 1);
            }
            else
            {
                IsPlaneCircle = false;
                if (normal.Length == 0.0)
                {
                    throw new Exception("法向量不能为0向量！");
                }
                Normal = normal;
            }

        }
        /// <summary>
        /// 点到圆的距离
        /// </summary>
        /// <param name="pt">点</param>
        /// <returns>距离值：当在圆内部时值为负值，在圆外部时为正值</returns>
        public double DistanceTo(Point pt)
        {
            Vector p = pt - Center;
            double sin = p.CrossProduct(Normal).Length / (p.Length * Normal.Length);
            return p.Length * sin - Radius;
        }
    }
}
